package restdom.validation.ruleengine;

import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.List;

import javax.rules.InvalidRuleSessionException;
import javax.rules.ObjectFilter;
import javax.rules.StatelessRuleSession;

import org.springframework.util.CollectionUtils;
import org.springmodules.jsr94.core.Jsr94Template;
import org.springmodules.jsr94.rulesource.RuleSource;
import org.springmodules.jsr94.support.StatelessRuleSessionCallback;
import org.springmodules.validation.util.condition.NonNullAcceptingCondition;

public class RuleEngineCondition extends NonNullAcceptingCondition {

	private String uri;

	private Jsr94Template template;

	private List<Object> helpers;

	public RuleEngineCondition(RuleSource ruleSource, String uri,
			List<Object> helpers) {
		this.uri = uri;
		this.template = new Jsr94Template(ruleSource);
		this.helpers = helpers;
	}

	@Override
	public boolean doCheck(Object object) {
		final List<Object> input = new ArrayList<Object>();
		if (!CollectionUtils.isEmpty(helpers)) {
			input.addAll(helpers);
		}
		input.add(object);

		final ObjectFilter filter = new ValidatedObjectFilter(object);

		List result = (List) template.executeStateless(uri, null,
				new StatelessRuleSessionCallback() {
					public Object execute(StatelessRuleSession session)
							throws InvalidRuleSessionException, RemoteException {
						return session.executeRules(input, filter);
					}
				});
		return !result.isEmpty();
	}

	private class ValidatedObjectFilter implements ObjectFilter {

		private static final long serialVersionUID = 5736996509955501055L;

		private Object instance;

		public ValidatedObjectFilter(Object instance) {
			this.instance = instance;
		}

		public Object filter(Object object) {
			return object == instance ? object : null;
		}

		public void reset() {
		}

	}
}
